package com.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class StringUtils extends org.apache.commons.lang3.StringUtils {
	@SuppressWarnings("unused")
	private static final String NULLSTR = "";
	@SuppressWarnings("unused")
	private static final char SEPARATOR = '_';

	public static <T> T nvl(T value, T defaultValue) {
		return value != null ? value : defaultValue;
	}

	public static boolean isEmpty(Collection<?> coll) {
		return (isNull(coll)) || (coll.isEmpty());
	}

	public static boolean isNotEmpty(Collection<?> coll) {
		return !isEmpty(coll);
	}

	public static boolean isEmpty(Object[] objects) {
		return (isNull(objects)) || (objects.length == 0);
	}

	public static boolean isNotEmpty(Object[] objects) {
		return !isEmpty(objects);
	}

	public static boolean isEmpty(Map<?, ?> map) {
		return (isNull(map)) || (map.isEmpty());
	}

	public static boolean isNotEmpty(Map<?, ?> map) {
		return !isEmpty(map);
	}

	public static boolean isEmpty(String str) {
		return (isNull(str)) || ("".equals(str.trim()));
	}
	
	public static boolean isEmptyOrStrNull(String str) {
		return (isNull(str)) || ("".equals(str.trim())) || str.equalsIgnoreCase("null");
	}
	
	public static boolean isNotEmptyOrStrNull(String str) {
		return !isEmptyOrStrNull(str);
	}

	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	public static boolean isNull(Object object) {
		return object == null;
	}

	public static boolean isNotNull(Object object) {
		return !isNull(object);
	}

	public static boolean isArray(Object object) {
		return (isNotNull(object)) && (object.getClass().isArray());
	}

	public static String trim(String str, String defult) {
		if (str == null) {
			return trim(defult);
		}
		return str.trim();
	}

	public static String trim(Object str) {
		if (str == null) {
			return "";
		}
		return str.toString().trim();
	}

	public static boolean hasText(String str) {
		return !"".equals(nonNull(str));
	}

	public static String nonNull(String str) {
		if (str == null) {
			return "";
		}
		return str;
	}

	public static String substring(String str, int start) {
		if (str == null) {
			return "";
		}
		if (start < 0) {
			start = str.length() + start;
		}
		if (start < 0) {
			start = 0;
		}
		if (start > str.length()) {
			return "";
		}
		return str.substring(start);
	}

	public static String substring(String str, int start, int end) {
		if (str == null) {
			return "";
		}
		if (end < 0) {
			end = str.length() + end;
		}
		if (start < 0) {
			start = str.length() + start;
		}
		if (end > str.length()) {
			end = str.length();
		}
		if (start > end) {
			return "";
		}
		if (start < 0) {
			start = 0;
		}
		if (end < 0) {
			end = 0;
		}
		return str.substring(start, end);
	}

	public static String format(String template, Object... params) {
		if ((isEmpty(params)) || (isEmpty(template))) {
			return template;
		}
		return StrFormatter.format(template, params);
	}

	public static String toUnderScoreCase(String s) {
		if (s == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		boolean upperCase = false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);

			boolean nextUpperCase = true;
			if (i < s.length() - 1) {
				nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
			}
			if ((i > 0) && (Character.isUpperCase(c))) {
				if ((!upperCase) || (!nextUpperCase)) {
					sb.append('_');
				}
				upperCase = true;
			} else {
				upperCase = false;
			}
			sb.append(Character.toLowerCase(c));
		}
		return sb.toString();
	}

	public static boolean inStringIgnoreCase(String str, String... strs) {
		if ((str != null) && (strs != null)) {
			for (String s : strs) {
				if (str.equalsIgnoreCase(trim(s))) {
					return true;
				}
			}
		}
		return false;
	}

	public static String convertToCamelCase(String name) {
		StringBuilder result = new StringBuilder();
		if ((name == null) || (name.isEmpty())) {
			return "";
		}
		if (!name.contains("_")) {
			return name.substring(0, 1).toUpperCase() + name.substring(1);
		}
		String[] camels = name.split("_");
		for (String camel : camels) {
			if (!camel.isEmpty()) {
				result.append(camel.substring(0, 1).toUpperCase());
				result.append(camel.substring(1).toLowerCase());
			}
		}
		return result.toString();
	}

	public static Double toDouble(Object val) {
		if (val == null) {
			return Double.valueOf(0.0D);
		}
		try {
			return Double.valueOf(trim(val.toString()));
		} catch (Exception e) {
		}
		return Double.valueOf(0.0D);
	}

	public static Float toFloat(Object val) {
		return Float.valueOf(toDouble(val).floatValue());
	}

	public static Long toLong(Object val) {
		return Long.valueOf(toDouble(val).longValue());
	}

	public static Integer toInteger(Object val) {
		return Integer.valueOf(toLong(val).intValue());
	}

	public static String replace(String src, String oldStr, String newStr) {
		StringBuffer result = new StringBuffer();
		boolean found = false;
		if ((src == null) || (oldStr == null) || (newStr == null)) {
			throw new NullPointerException("parameter is null");
		}
		if (oldStr.length() == 0) {
			throw new IllegalArgumentException("illegal parameter");
		}
		int pos = 0;
		int pos1 = 0;
		while (pos < src.length()) {
			pos1 = src.indexOf(oldStr, pos);
			if (pos1 < 0) {
				pos1 = src.length();
				found = false;
			} else {
				found = true;
			}
			result.append(src.substring(pos, pos1));
			if (found) {
				result.append(newStr);
				pos = pos1 + oldStr.length();
			} else {
				pos = pos1;
			}
		}
		return result.toString();
	}

	public static boolean booleanStr2boolen(String booleanStr) {
		return hasText(booleanStr) ? new Boolean(booleanStr).booleanValue() : false;
	}

	public static String uppercaseToLowercaseUnderline(String str) {
		if (!hasText(str)) {
			return null;
		}
		for (int i = 0; i < str.length(); i++) {
			str = str.substring(0, 1).toLowerCase() + str.substring(1);
			if (Character.isUpperCase(str.charAt(i))) {
				String big = str.substring(i, i + 1);
				str = str.replaceFirst(big, '_' + big.toLowerCase());
			}
		}
		return str;
	}

	public static String uppercaseToLowercaseSpace(String str) {
		if (!hasText(str)) {
			return null;
		}
		String result = str;
		for (int i = 0; i < str.length(); i++) {
			if (Character.isUpperCase(str.charAt(i))) {
				String big = str.substring(i, i + 1);
				result = result.replaceFirst(big, " " + big.toUpperCase());
			}
		}
		result = result.substring(0, 1).toUpperCase() + result.substring(1);
		return result;
	}

	/**
	 * 提供指定数值的（精确）小数位四舍五入处理。
	 *
	 * @param value 需要四舍五入的数字
	 * @param scale 小数点后保留几位
	 * @return 四舍五入后的结果
	 */
	public static double round(double value, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(value));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
	}

	/**
	 * @Title: getCtime
	 * @Description: 打印时间处理
	 * @param: @return
	 * @return: String
	 * @author ljp
	 * @Date 2016年10月12日 下午8:49:03
	 */
	public static String getCtime() {
		Calendar dt = Calendar.getInstance();
		dt.setTime(new Date());
		String tmp = String.valueOf(dt.get(1));
		int m = dt.get(2) + 1;
		String mm = "";
		if (m < 10) {
			mm = mm + "0";
		}
		mm = mm + String.valueOf(m);

		int d = dt.get(5);
		String dd = "";
		if (d < 10) {
			dd = dd + "0";
		}
		dd = dd + String.valueOf(d);

		int h = dt.get(11);
		String hh = "";
		if (h < 10) {
			hh = hh + "0";
		}
		hh = hh + String.valueOf(h);

		int min = dt.get(12);
		String minute = "";
		if (min < 10) {
			minute = minute + "0";
		}
		minute = minute + String.valueOf(min);

		int s = dt.get(13);
		String ss = "";
		if (s < 10) {
			ss = ss + "0";
		}
		ss = ss + String.valueOf(s);

		return tmp + mm + dd + hh + minute + ss;
	}

	/**
	 * 过滤表情字符 如果是shope，增加url过滤
	 * 
	 * @param str 字符串
	 * @return string
	 */
	public static String filterSpecialChar(String str) {
		if (StringUtils.isNotBlank(str)) {
			str = str.replaceAll("[\uD83C\uDC00-\uD83C\uDFFF]|[\uD83D\uDC00-\uD83D\uDFFF]|[\u2600-\u27ff]", "");
		}
		if (str.contains("shopee.")) {
			String sitUrl = "", sit = "", shopIdAndItemId = "", shopId = "", itemId = "";

			if (str.contains("https://")) {
				sitUrl = str.substring(str.indexOf("https://") + 8);
				sit = sitUrl.substring(0, sitUrl.indexOf("/"));
			} else if (str.contains("http://")) {
				sitUrl = str.substring(str.indexOf("http://") + 7);
				sit = sitUrl.substring(0, sitUrl.indexOf("/"));
			}
			if (sitUrl.contains("-i.")) {
				shopIdAndItemId = sitUrl.substring(sitUrl.indexOf("-i.") + 3);
				shopId = shopIdAndItemId.substring(0, shopIdAndItemId.indexOf("."));
				itemId = shopIdAndItemId.substring(shopIdAndItemId.indexOf(".") + 1);
			} else if (sitUrl.contains("/product/")) {
				shopIdAndItemId = sitUrl.substring(sitUrl.indexOf("/product/") + 9);
				shopId = shopIdAndItemId.substring(0, shopIdAndItemId.indexOf("/"));
				itemId = shopIdAndItemId.substring(shopIdAndItemId.indexOf("/") + 1);
				if (itemId.contains("/")) {
					itemId = itemId.replace("/", "");
				}
			}
			str = "https://" + sit + "/product/" + shopId + "/" + itemId;
		}
		return str;
	}
	
	/**
	 * 拷贝List列表
	 * @param sourceList
	 * @return
	 */
	public static List<String> copyList(List<String> sourceList) {
		List<String> newList = new ArrayList<>();
		if(!CollectionUtils.isEmpty(sourceList)) {
			for(String data:sourceList) {
				newList.add(data);
			}
		}
		return newList;
	}

	/**
	 * 判断是否为JSONArray格式
	 */
	public static boolean isJsonArray(String str) {
		if (StringUtils.isBlank(str))
			return false;
		StringUtils.isEmpty(str);
		try {
			JSONArray.fromObject(str);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 判断是否为JSONObject格式
	 */
	public static boolean isJsonObject(String str) {
		if (StringUtils.isBlank(str))
			return false;
		StringUtils.isEmpty(str);
		try {
			JSONObject.fromObject(str);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
}
